package com.coderman.infosys.auth.app.facadeimpl.user;

import com.coderman.infosys.auth.app.command.AddUserGroupCmd;
import com.coderman.infosys.auth.app.convert.UserGroupConvert;
import com.coderman.infosys.auth.app.executor.UserGroupCmdExe;
import com.coderman.infosys.auth.domain.bo.event.UserGroupCreatedEvent;
import com.coderman.infosys.auth.domain.bo.user.UserGroupBO;
import com.coderman.infosys.auth.domain.enums.errors.UserGroupErrorEnum;
import com.coderman.infosys.auth.domain.utils.AppEventPublisher;
import com.coderman.infosys.plat.auth.common.behavior.UserGroupOpEnum;
import com.coderman.infosys.plat.auth.common.dto.ResultDataDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.coderman.infosys.auth.api.dto.user.UserGroupDTO;
import com.coderman.infosys.auth.api.dto.user.request.UpdateUserGroupRequestDTO;
import com.coderman.infosys.auth.api.dto.user.request.CreateUserGroupRequestDTO;
import com.coderman.infosys.auth.api.facade.user.UserGroupFacade;
import org.apache.dubbo.config.annotation.Service;
import com.coderman.infosys.auth.domain.repository.UserRoleRepository;
import org.springframework.transaction.annotation.Transactional;


/**
 * @Description:接口实现类
 * @Author：
 * @CreateTime：2022-01-02 15:27:39
 * @version v1.0
 */
@Service
public class UserGroupFacadeImpl   implements UserGroupFacade{

	private  Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private UserRoleRepository userRoleRepository;

    @Autowired
    private UserGroupCmdExe userGroupCmdExe;

    @Autowired
    private AppEventPublisher appEventPublisher;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDataDto<UserGroupDTO> createUserGroup(CreateUserGroupRequestDTO createUserGroupRequestDTO){
        /*
        这里注释的内容是基于代码生成的，也就是简单的调用下层处理
        //一.假设这是第一种实现方案面向过程式的，facade充当api接口实现和应用层包括数据的整体封装转换逻辑
        UserGroupBO userGroupBO = UserGroupConvert.INSTANCE.dto2bo(createUserGroupRequestDTO);
        userRoleRepository.registUserGroup(userGroupBO);*/

        //二.现在我们看一下基于cmd的方式来优化一下,算是第二种实现方案面向cmd的
        //很多逻辑被cmd处理掉了,facade充当api接口实现和应用层，当然这显得非常清爽
        AddUserGroupCmd addUserGroupCmd = AddUserGroupCmd.buildCmd(createUserGroupRequestDTO);
        //1.判断是否满足用户数限制
        if(addUserGroupCmd.satisfyUserCount()){
            //由于加了事务了，这里抛出异常会更合适一些
            return ResultDataDto.fail(UserGroupErrorEnum.USER_COUNT_OVER_ERROR);
        }

        UserGroupBO userGroupBO = addUserGroupCmd.buildUserGroupBO(createUserGroupRequestDTO);
        //2.准备持久化用户组信息
        userRoleRepository.registUserGroup(addUserGroupCmd.buildUserGroupBO(createUserGroupRequestDTO));
        //3.发送事务成功事件,由于这里是带有事务的消息并且是异步的事件，所以为了保证业务逻辑的顺序性和完整性,事务逻辑建议在应用层
        //参考eventHandler包
        appEventPublisher.publish(new UserGroupCreatedEvent(this,userGroupBO));

        //三.现在我们看一下把第二种实现方案放到userGroupCmdExe中，把下面的一行注释打开
        //userGroupCmdExe.exe(UserGroupOpEnum.CREATE_OR_RELATE_ROLE_ROLEGROUP,addUserGroupCmd);

        return ResultDataDto.success();
    }

    @Override
    public ResultDataDto<Boolean> updateUserGroup(UpdateUserGroupRequestDTO updateUserGroupRequestDTO){
        UserGroupBO userGroupBO = UserGroupConvert.INSTANCE.dto2bo(updateUserGroupRequestDTO);

        userRoleRepository.updateUserGroup(userGroupBO);
        return ResultDataDto.success();
    }

    @Override
    public ResultDataDto<Boolean> updateUserGroupStatus(String groupCode,Integer status){
        UserGroupBO userGroupBO = userRoleRepository.getByUserGroupCode(groupCode);
        userGroupBO.setStatus(status);

        int intVar = userRoleRepository.updateUserGroup(null);

        return null;
    }

}